using System;
using System.Collections.Specialized;
using System.Web.UI;
using System.IO;

namespace Library.WebControls {

	///<summary>
	/// Base of Page class
	///</summary>
	public abstract class BasePage : Page {
		internal class Text {
			public string ConfirmDelete = "Are you sure?";
			public string NoItem = "No item display";
			public string Refresh = "Refresh";
			public string New = "New";
			public string Edit = "Edit";
			public string Save = "Save";
			public string Delete = "Delete";
			public string NextPage = "Next page";
			public string PreviewPage = "Priview page";
			public string FirstPage = "First page";
			public string LastPage = "Last page";
			public string Clear = "Clear";
			public string Page = "Page";
			public string RowPerPage = "Row per page";
			public string View = "View";
			public string Today = "Today";
			public string In = "of";
			internal readonly StringDictionary NameValues = new StringDictionary();

		}
		/// <summary>
		/// Get value read from lib.txt or lib[LangCode].txt by specific key
		/// </summary>
		/// <param name="key"></param>
		/// <returns></returns>
		public string GetTextFromTextConfig(string key) {
			return CulText.NameValues[key];
		}

		private Text _culText;
		internal Text CulText {
			get {
				if (_culText == null) {
					_culText = new Text();
					string langShortName = String.Empty;
					var lang = CurrentLanguage;
					if (lang != null) {
						langShortName = "." + lang.ShortName;
					}
					var filePath = MapPath("~/App_Data/lib" + langShortName + ".txt");
					if (!File.Exists(filePath) && !String.IsNullOrEmpty(langShortName)) filePath = MapPath("~/App_Data/lib.txt");
					if (File.Exists(filePath)) {
						using (var file = new StreamReader(filePath)) {
							string line = file.ReadLine();
							while (line != null) {
								line = line.Trim();
								if (!line.StartsWith("//")) {
									string key = String.Empty;
									string value = String.Empty;
									for (int i = 0; i < line.Length; i++) {
										var c = line[i];
										if (c == ' ') continue;
										if (c == '\t') continue;

										if (c == '=') {
											value = line.Substring(i + 1);
											break;
										} else {
											key += c;
										}
									}

									switch (key) {
										case "ConfirmDelete":
											_culText.ConfirmDelete = value;
											break;
										case "NoItemText":
											_culText.NoItem = value;
											break;
										case "Refresh":
											_culText.Refresh = value;
											break;
										case "New":
											_culText.New = value;
											break;
										case "Edit":
											_culText.Edit = value;
											break;
										case "Save":
											_culText.Save = value;
											break;
										case "Delete":
											_culText.Delete = value;
											break;
										case "NextPage":
											_culText.NextPage = value;
											break;
										case "PreviewPage":
											_culText.PreviewPage = value;
											break;
										case "FirstPage":
											_culText.FirstPage = value;
											break;
										case "LastPage":
											_culText.LastPage = value;
											break;
										case "Page":
											_culText.Page = value;
											break;
										case "In":
											_culText.In = value;
											break;
										case "RowPerPage":
											_culText.RowPerPage = value;
											break;
										case "View":
											_culText.View = value;
											break;
										case "Today":
											_culText.Today = value;
											break;
										case "Clear":
											_culText.Clear = value;
											break;

									}
									try {
										_culText.NameValues.Add(key, value);
									} catch (ArgumentException) {
										throw new Exception(String.Format("Duplicate value {0} in file {1}", key, filePath));
									}
								}
								line = file.ReadLine();
							}
						}
					}


				}
				return _culText;
			}
		}




		public bool IsLibraryWebControlCallback {
			get { return BaseControl.IsLibraryWebControlCallback(this); }
		}
		public const string CurrentUserKey = "Library.WebControls.BasePage.CurrentUserKey";
		public const string CurrentLanguageKey = "Library.WebControls.BasePage.CurrentLanguageKey";
		public virtual object CurrentUser {
			get {
				return Session[CurrentUserKey];
			}
			set {
				Session[CurrentUserKey] = value;
			}
		}
		public virtual Language CurrentLanguage {
			get {
				return Session[CurrentLanguageKey] as Language;
			}
			set {

				Session[CurrentLanguageKey] = value;
			}
		}
		public virtual void ApplyPageLanguage(Language lang) {
			SetPageLanguage(lang);
			Response.Redirect(Request.Url.AbsoluteUri);
		}
		private void SetPageLanguage(Language lang) {
			CurrentLanguage = lang;
			Page.Culture = lang.ShortName;
			Page.UICulture = lang.ShortName;
		}
		protected override void InitializeCulture() {
			base.InitializeCulture();
			Language lang = CurrentLanguage;
			if (lang != null) {
				SetPageLanguage(CurrentLanguage);
			}
		}
		protected override void OnLoad(EventArgs e) {
			if (IsSecurePage) {
				if (CurrentUser == null) {
					if (!IsCallback && !BaseControl.IsLibraryWebControlCallback(this)) {
						if (String.IsNullOrEmpty(LoginPage)) {
							throw new Exception("User is not authorized, can not redirect empty login page. Check override LoginPage");
						}
						Response.Redirect(LoginPage);
						return;
					}
				}
			}
			base.OnLoad(e);
		}


		public virtual bool IsSecurePage { get { return true; } }
		protected virtual string LoginPage {
			get { return String.Empty; }
		}
		public class Language {
			public string ShortName { get; private set; }
			public int Id { get; private set; }
			public Language(int id, string shortName) {
				Id = id;
				ShortName = shortName;
			}
		}

		protected internal virtual void OnSimpleCallbackThrowException(BaseControl controlThrowException, Exception exception, out bool handled, out string message) {
			handled = false;
			message = exception == null ? String.Empty : String.Format("{0}: {1}", exception.GetType().FullName, exception.Message);
		}
	}
}
